package com.pay.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.pay.common.pay.utils.SignUtil;
import com.pay.config.BodyReaderWrapper;
import com.pay.entity.MerchantSecretKeyDO;
import com.pay.service.MerchantSecretKeyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

// @Component
@Slf4j
public class InterceptionVerification implements HandlerInterceptor {
    @Autowired
    private MerchantSecretKeyService merchantSecretKeyService;

    /**
     * 拦截所有的请求  执行请求业务代码之前
     * 如果返回preHandle = true 则可以到我们目标方法
     * 如果返回preHandle = false 无法执行到我们目标方法
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 在请求处理前执行的逻辑
        //1.获取json数据
        String parametersStr = getParameters(request);
        JSONObject jsonObject = JSONObject.parseObject(parametersStr);
        //2.验证appid和appkey 是否正确
        String appId = request.getHeader("appId");
        if (StringUtils.isEmpty(appId)) {
            setResponseFail(response, "appId is null");
            return Boolean.FALSE;
        }
        String appKey = request.getHeader("appKey");
        if (StringUtils.isEmpty(appKey)) {
            setResponseFail(response, "appKey is null");
            return Boolean.FALSE;
        }
        // 从数据库中获取到当前商户的信息,包括qppid,appkey,salt, permissionList
        MerchantSecretKeyDO merchantSecret = merchantSecretKeyService.getByAppIdKeyMerchantSecret(appId, appKey);
        if (merchantSecret == null) {
            setResponseFail(response, "appid或者appkey不正确!");
            return Boolean.FALSE;
        }
        //3.验证是否允许访问该权限
        String servletPath = request.getServletPath();
        String permissionList = merchantSecret.getPermissionList();
        boolean existsPermission = existsPermission(servletPath,permissionList);
        if (!existsPermission) {
            setResponseFail(response, "权限不足!");
                return Boolean.FALSE;
        }
        
        //4.有权限 验证签名 防止黑客篡改数据
        // 获取前端传递过来的sign
        String sign = request.getParameter("sign");
        if (StringUtils.isEmpty(sign)) {
            setResponseFail(response, "sign is null");
            return Boolean.FALSE;
        }
        String timestamp = request.getParameter("timestamp");
        if (StringUtils.isEmpty(timestamp)) {
            setResponseFail(response, "sign is null");
            return Boolean.FALSE;
        }
        String saltKey = merchantSecret.getSaltKey();
        boolean verifyJsonResult = SignUtil.verifyJson(sign, timestamp,jsonObject.toJSONString(),saltKey);
        if (!verifyJsonResult) {
            setResponseFail(response, "验证签名失败!");
            return Boolean.FALSE;
        }
        // 返回 true 允许请求继续，返回 false 则终止请求
        return Boolean.TRUE;
    }

    public void setResponseOk(HttpServletResponse response) throws IOException {
        setResponse(response, 200, "ok");
    }

    public void setResponseFail(HttpServletResponse response, String msg) throws IOException {
        setResponse(response, 500, msg);
    }

    public void setResponse(HttpServletResponse response, Integer code, String msg) throws IOException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Cache-Control", "no-cache");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        JSONObject result = new JSONObject();
        result.put("code", code);
        result.put("msg", msg);
        response.getWriter().println(result.toJSONString());
        response.getWriter().flush();
    }

    //获取参数
    public static String getParameters(HttpServletRequest request) throws IOException {
        BodyReaderWrapper apiSignRequestWrapper = new BodyReaderWrapper(request);
        BufferedReader streamReader = new BufferedReader(new InputStreamReader(apiSignRequestWrapper.getInputStream(), "UTF-8"));
        StringBuilder responseStrBuilder = new StringBuilder();
        String inputStr;
        while ((inputStr = streamReader.readLine()) != null){
            responseStrBuilder.append(inputStr);
        }
        return responseStrBuilder.toString();
    }
    
    // 判断当前商户是否有操作某个接口的权限
    private boolean existsPermission(String servletPath, String permissionList){
        String[] permissionUrls = permissionList.split(",");
        for(String permissionUrl : permissionUrls){
            if (permissionUrl.equals(servletPath)){
                return Boolean.TRUE;
            }
        }
        return Boolean.FALSE;
    }
}